﻿/*****************************************介绍*****************************************
 * 作者：Ywh
 * 创建时间：2025-05-17 15:18:46
 * 功能：所有UI面板的基类
**************************************************************************************/

//using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace Game.Framework
{
    [DisallowMultipleComponent]
    [RequireComponent(typeof(UIController))]
    public abstract class BasePanel : MonoBehaviour
    {
        private UIController m_Controller;

        protected virtual void Awake()
        {
            m_Controller = GetComponent<UIController>();
            m_Controller.Init();
            RegistAny();
            InitUI();
        }

        protected virtual void OnDestroy()
        {
            Clear();
        }

        protected abstract void RegistAny();

        protected abstract void UnregistAny();

        protected virtual void InitUI() { }

        /// <summary>打开面板时执行该函数，执行时机在OnEnable之后</summary>
        public virtual void Init(object data) { }

        public virtual void Hide(bool isDestroy = false)
        {
            if (isDestroy)
                Destroy(gameObject);
            else
                gameObject.SetActive(false);
        }

        /// <summary>获取指定的矩形变换</summary>
        /// <param name="name">节点名称不包含<see cref="UIController.RECT_END"/> 和 <see cref="UIController.BREAK_HEAD"/>的部分</param>
        /// <param name="error">如果找不到组件则不为""</param>
        public RectTransform GetRect(string name)
        {
            var result = m_Controller.GetRect(name, out var error);
            if (result == null)
                LogManager.LogError(error, "BasePanel", "GetRect");
            return result;
        }

        /// <summary>获取指定的控件</summary>
        /// <typeparam name="T">想要获取的组件类型，例如：<see cref="Button"/></typeparam>
        /// <param name="name">节点名称不包含<see cref="UIController.CTRL_END"/> 和 <see cref="UIController.BREAK_HEAD"/>的部分</param>
        /// <param name="error">如果找不到组件则不为""</param>
        /// <returns>找不到返回null，反之返回对应类型的组件</returns>
        public T GetControl<T>(string name) where T : UIBehaviour
        {
            var result = m_Controller.GetControl<T>(name, out var error);
            if (result == null)
                LogManager.LogError(error, "BasePanel", "GetCtrl");
            return result;
        }

        public void Clear()
        {
            UnregistAny();
            if (m_Controller) m_Controller.Clear();
        }

        public int RectCount => m_Controller.RectCount;

        public int CtrlCount => m_Controller.CtrlCount;

        #region 监听可交互控件

        private void AddListening_Button(object data)
        {
            object[] infos = data as object[];
            string name = infos[0].ToString();
            Button ctrl = infos[1] as Button;
            ctrl.onClick.AddListener(() => ClickBtnHandle(name));
        }
        private void AddListening_Toggle(object data)
        {
            object[] infos = data as object[];
            string name = infos[0].ToString();
            Toggle ctrl = infos[1] as Toggle;
            ctrl.onValueChanged.AddListener(isOn => ClickToggleHandle(name, isOn));
        }
        private void AddListening_Slider(object data)
        {
            object[] infos = data as object[];
            string name = infos[0].ToString();
            Slider ctrl = infos[1] as Slider;
            ctrl.onValueChanged.AddListener(value => SliderValueChangeHandle(name, value));
        }
        private void AddListening_Scrollbar(object data)
        {
            object[] infos = data as object[];
            string name = infos[0].ToString();
            Scrollbar ctrl = infos[1] as Scrollbar;
            ctrl.onValueChanged.AddListener(value => ScrollbarValueChangeHandle(name, value));
        }
        private void AddListening_InputField(object data)
        {
            object[] infos = data as object[];
            string name = infos[0].ToString();
            InputField ctrl = infos[1] as InputField;
            ctrl.onValueChanged.AddListener(text => InputFieldValueChangeHandle(name, text));
            ctrl.onEndEdit.AddListener(text => InputFieldEndEditHandle(name, text));
            ctrl.onSubmit.AddListener(text => InputFieldSubmitHandle(name, text));
        }
        //private void AddListening_TMP_InputField(object data)
        //{
        //    object[] infos = data as object[];
        //    string name = infos[0].ToString();
        //    TMP_InputField ctrl = infos[1] as TMP_InputField;
        //    ctrl.onValueChanged.AddListener(text => TMP_InputFieldValueChangeHandle(name, text));
        //    ctrl.onEndEdit.AddListener(text => TMP_InputFieldEndEditHandle(name, text));
        //    ctrl.onSubmit.AddListener(text => TMP_InputFieldSubmitHandle(name, text));
        //}
        private void AddListening_ScrollRect(object data)
        {
            object[] infos = data as object[];
            string name = infos[0].ToString();
            ScrollRect ctrl = infos[1] as ScrollRect;
            ctrl.onValueChanged.AddListener(pos => ScrollRectValueChangeHandle(name, pos));
        }
        private void AddListening_Dropdown(object data)
        {
            object[] infos = data as object[];
            string name = infos[0].ToString();
            Dropdown ctrl = infos[1] as Dropdown;
            ctrl.onValueChanged.AddListener(index => DropdownValueChangeHandle(name, index));
        }
        //private void AddListening_TMP_Dropdown(object data)
        //{
        //    object[] infos = data as object[];
        //    string name = infos[0].ToString();
        //    TMP_Dropdown ctrl = infos[1] as TMP_Dropdown;
        //    ctrl.onValueChanged.AddListener(index => TMP_DropdownValueChangeHandle(name, index));
        //}

        #endregion

        #region 移除可交互组件的监听
        private void RemoveListening_Button(Button ctrl)
        {
            ctrl.onClick.RemoveAllListeners();
        }
        private void RemoveListening_Toggle(Toggle ctrl)
        {
            ctrl.onValueChanged.RemoveAllListeners();
        }
        private void RemoveListening_Slider(Slider ctrl)
        {
            ctrl.onValueChanged.RemoveAllListeners();
        }
        private void RemoveListening_Scrollbar(Scrollbar ctrl)
        {
            ctrl.onValueChanged.RemoveAllListeners();
        }
        private void RemoveListening_InputField(InputField ctrl)
        {
            ctrl.onValueChanged.RemoveAllListeners();
            ctrl.onEndEdit.RemoveAllListeners();
            ctrl.onSubmit.RemoveAllListeners();
        }
        //private void RemoveListening_TMP_InputField(TMP_InputField ctrl)
        //{
        //    ctrl.onValueChanged.RemoveAllListeners();
        //    ctrl.onEndEdit.RemoveAllListeners();
        //    ctrl.onSubmit.RemoveAllListeners();
        //}
        private void RemoveListening_ScrollRect(ScrollRect ctrl)
        {
            ctrl.onValueChanged.RemoveAllListeners();
        }
        private void RemoveListening_Dropdown(Dropdown ctrl)
        {
            ctrl.onValueChanged.RemoveAllListeners();
        }
        //private void RemoveListening_TMP_Dropdown(TMP_Dropdown ctrl)
        //{
        //    ctrl.onValueChanged.RemoveAllListeners();
        //}
        #endregion

        #region 控件触发事件

        protected virtual void ClickBtnHandle(string name) { }
        protected virtual void ClickToggleHandle(string name, bool isOn) { }
        protected virtual void SliderValueChangeHandle(string name, float value) { }
        protected virtual void ScrollbarValueChangeHandle(string name, float value) { }
        protected virtual void InputFieldValueChangeHandle(string name, string text) { }
        protected virtual void InputFieldEndEditHandle(string name, string text) { }
        protected virtual void InputFieldSubmitHandle(string name, string text) { }
        protected virtual void TMP_InputFieldValueChangeHandle(string name, string text) { }
        protected virtual void TMP_InputFieldEndEditHandle(string name, string text) { }
        protected virtual void TMP_InputFieldSubmitHandle(string name, string text) { }
        protected virtual void ScrollRectValueChangeHandle(string name, Vector2 pos) { }
        protected virtual void DropdownValueChangeHandle(string name, int index) { }
        protected virtual void TMP_DropdownValueChangeHandle(string name, int index) { }

        #endregion
    }
}